using Mono.Cecil;
using Mono.Cecil.Cil;

namespace Cil.Ast;

public sealed class CatchBlockExpression : Expression
{
	public const int BodyPos = 0;
	private const int MaxNodes = 1;

	private readonly IFixedList<Expression> _handlersContainer = new FixedList<Expression>(MaxNodes);

	public CatchBlockExpression(Context context, TypeReference ref_catchType, Expression exp_catch) : base(context)
	{
		Nodes = _handlersContainer;
		Test = ref_catchType;
		Body = exp_catch;
	}

	public CatchBlockExpression(Context context, TypeReference ref_exception) : base(context)
	{
		Test = ref_exception;
		Body = new GroupExpression(context);
		Nodes = _handlersContainer;
		Body.ParentNode = this;
	}

	public TypeReference Test { get; private set; }

	public VariableReference VariableReference { get; set; }

	public Expression Body
	{
		get { return _handlersContainer[BodyPos]; }
		private set { _handlersContainer[BodyPos] = value; value.ParentNode = this; }
	}

	public override string ToString()
	{
		if(Test.MetadataType == MetadataType.Object)
		{
			return string.Format("catch {{ {0} }}", Body);
		}
		else
		{
			return string.Format("catch({0}{1}){{ {2} }}", Test, VariableReference == null ? "" : " " + VariableReference, Body);
		}
	}
}